import os
import uuid
import shutil
import tempfile
from fastapi import APIRouter, UploadFile, File, Form, Depends, HTTPException, BackgroundTasks
from fastapi.responses import JSONResponse, FileResponse
from sqlalchemy.orm import Session
from typing import List, Optional
from datetime import datetime

from api.schemas.compile import (
    CompileOptions, CompileRequest, CompileResponse, 
    CompileStatusResponse, CompileResultResponse
)
from db.database import get_db
from services.compile_service import (
    create_compilation_task, get_compilation_status, 
    get_compilation_result, save_uploaded_files,
    compile_files_task
)
from utils.file_handling import ensure_directory
from db.models import CompilationHistory
from loguru import logger

router = APIRouter()

@router.post("/start", response_model=CompileResponse)
async def start_compilation(
    background_tasks: BackgroundTasks,
    files: List[UploadFile] = File(...),
    optimize: int = Form(2),
    python_version: str = Form("3"),
    platform: str = Form("linux"),
    keep_source: bool = Form(False),
    zip_output: bool = Form(False),
    delete_temp: bool = Form(True),
    extra_args: Optional[str] = Form(None),
    output_dir: Optional[str] = Form(None),
    db: Session = Depends(get_db)
):
    """开始编译任务"""
    try:
        # 验证文件类型
        for file in files:
            if not (file.filename.endswith(".py") or file.filename.endswith(".zip")):
                raise HTTPException(
                    status_code=400,
                    detail=f"不支持的文件类型: {file.filename}。仅支持 .py 和 .zip 文件。"
                )
        
        # 生成任务ID
        task_id = str(uuid.uuid4())
        
        # 创建编译选项
        options = CompileOptions(
            optimize=optimize,
            python_version=python_version,
            platform=platform,
            keep_source=keep_source,
            zip_output=zip_output,
            delete_temp=delete_temp,
            extra_args=extra_args,
            output_dir=output_dir
        )
        
        # 创建编译任务记录
        task = create_compilation_task(db, task_id, options, files)
        
        # 保存上传的文件
        upload_dir = ensure_directory(os.path.join("uploads", task_id))
        save_uploaded_files(files, upload_dir)
        
        # 将编译任务添加到后台任务
        background_tasks.add_task(compile_files_task, task_id, upload_dir, options, db)
        
        logger.info(f"编译任务已启动: {task_id}")
        return {
            "task_id": task_id,
            "status": "pending",
            "message": "编译任务已启动"
        }
    except Exception as e:
        logger.error(f"启动编译任务失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"启动编译任务失败: {str(e)}")

@router.get("/status/{task_id}", response_model=CompileStatusResponse)
async def get_compile_status(task_id: str, db: Session = Depends(get_db)):
    """获取编译任务状态"""
    status_info = get_compilation_status(db, task_id)
    if not status_info:
        raise HTTPException(status_code=404, detail="编译任务不存在")
    return status_info

@router.get("/result/{task_id}", response_model=CompileResultResponse)
async def get_compile_result(task_id: str, db: Session = Depends(get_db)):
    """获取编译结果"""
    result = get_compilation_result(db, task_id)
    if not result:
        raise HTTPException(status_code=404, detail="编译任务不存在")
    if result["status"] not in ["success", "failed"]:
        raise HTTPException(status_code=400, detail="编译任务尚未完成")
    return result

@router.get("/download/{task_id}/{filename}")
async def download_compiled_file(task_id: str, filename: str, db: Session = Depends(get_db)):
    """下载编译后的文件"""
    # 验证任务是否存在且已完成
    task = db.query(CompilationHistory).filter(
        CompilationHistory.task_id == task_id,
        CompilationHistory.status == "success"
    ).first()
    
    if not task:
        raise HTTPException(status_code=404, detail="编译任务不存在或未成功完成")
    
    # 构建文件路径
    file_path = os.path.join("outputs", task_id, filename)
    
    if not os.path.exists(file_path):
        raise HTTPException(status_code=404, detail="文件不存在")
    
    return FileResponse(
        path=file_path,
        filename=filename,
        media_type="application/octet-stream"
    )

@router.get("/download-all/{task_id}")
async def download_all_files(task_id: str, db: Session = Depends(get_db)):
    """下载所有编译后的文件（打包为zip）"""
    # 验证任务是否存在且已完成
    task = db.query(CompilationHistory).filter(
        CompilationHistory.task_id == task_id,
        CompilationHistory.status == "success"
    ).first()
    
    if not task:
        raise HTTPException(status_code=404, detail="编译任务不存在或未成功完成")
    
    # 构建输出目录路径
    output_dir = os.path.join("outputs", task_id)
    
    if not os.path.exists(output_dir):
        raise HTTPException(status_code=404, detail="输出文件不存在")
    
    # 创建临时文件用于打包
    with tempfile.NamedTemporaryFile(delete=False, suffix=".zip") as tmp_file:
        tmp_filename = tmp_file.name
    
    # 打包文件
    shutil.make_archive(
        tmp_filename.replace(".zip", ""),
        "zip",
        output_dir
    )
    
    # 返回zip文件
    return FileResponse(
        path=tmp_filename,
        filename=f"py2so_output_{task_id}.zip",
        media_type="application/zip"
    )
